<?php
/**
 * CONTENIDO extension pack (mpContenidoX), consists of multiple classes to
 * provide more features for Plugins/Modules.
 *
 * @package     mpContenidoX
 * @subpackage  Array_Management
 * @author      Murat Purc <murat@purc.de>
 * @copyright   Copyright (c) 2008-2012 Murat Purc (http://www.purc.de)
 * @license     http://www.gnu.org/licenses/gpl-2.0.html - GNU General Public License, version 2
 * @version     $Id: mpArrayManager.class.php 21 2012-07-16 21:33:14Z purcaholic $
 */


defined('CON_FRAMEWORK') or die('Illegal call');


/**
 * Abstract array manager class.
 *
 * Provides access to multidimensional arrays up to deepness of 4 levels.
 *
 * @package     mpContenidoX
 * @subpackage  Array_Management
 * @author      Murat Purc <murat@purc.de>
 * @todo        Comment code
 */
abstract class mpArrayManager implements mpArrayManager_Interface
{

    /**
     * Contains the array to manage.
     * @var  array
     */
    protected $_aData;

    /**
     * The delemiter beeing used to access to array structure.
     * @var  string
     */
    protected $_delem = '/';


    public function exists($path)
    {
        $a = $this->_getSections($path);

        $count = count($a);

        if ($count == 1 && is_array($this->_aData) && isset($this->_aData[$a[0]])) {
            // 1. level
            return true;
        } elseif ($count == 2 && is_array($this->_aData[$a[0]]) && isset($this->_aData[$a[0]][$a[1]])) {
            // 2. level
            return true;
        } elseif ($count == 3 && is_array($this->_aData[$a[0]][$a[1]]) && isset($this->_aData[$a[0]][$a[1]][$a[2]])) {
            // 3. level
            return true;
        } elseif ($count == 4 && is_array($this->_aData[$a[0]][$a[1]][$a[2]]) && isset($this->_aData[$a[0]][$a[1]][$a[2]][$a[3]])) {
            // 4. level
            return true;
        }

        return false;
    }


    public function get($path, $default=null)
    {
        $a = $this->_getSections($path);

        $count = count($a);

        if ($count == 1 && is_array($this->_aData) && isset($this->_aData[$a[0]])) {
            // 1. level
            return $this->_aData[$a[0]];
        } elseif ($count == 2 && is_array($this->_aData[$a[0]]) && isset($this->_aData[$a[0]][$a[1]])) {
            // 2. level
            return $this->_aData[$a[0]][$a[1]];
        } elseif ($count == 3 && is_array($this->_aData[$a[0]][$a[1]]) && isset($this->_aData[$a[0]][$a[1]][$a[2]])) {
            // 3. level
            return $this->_aData[$a[0]][$a[1]][$a[2]];
        } elseif ($count == 4 && is_array($this->_aData[$a[0]][$a[1]][$a[2]]) && isset($this->_aData[$a[0]][$a[1]][$a[2]][$a[3]])) {
            // 4. level
            return $this->_aData[$a[0]][$a[1]][$a[2]][$a[3]];
        }

        // return default value
        return $default;
    }


    public function set($path, $value)
    {
        $a = $this->_getSections($path);

        // pre check of section depth
        $count = count($a);

        if ($count > 1 && !isset($this->_aData[$a[0]])) {
            $this->_aData[$a[0]] = array();
        }

        if ($count > 2 && !isset($this->_aData[$a[0]][$a[1]])) {
            $this->_aData[$a[0]][$a[1]] = array();
        }

        if ($count > 3 && !isset($this->_aData[$a[0]][$a[1]][$a[2]])) {
            $this->_aData[$a[0]][$a[1]][$a[2]] = array();
        }

        if ($count == 1) {
            // set at 1. level
            $this->_aData[$a[0]] = $value;
        } elseif ($count == 2) {
            // set at 2. level
            $this->_aData[$a[0]][$a[1]] = $value;
        } elseif ($count == 3) {
            // set at 3. level
            $this->_aData[$a[0]][$a[1]][$a[2]] = $value;
        } else {
            // set at 4. level
            $this->_aData[$a[0]][$a[1]][$a[2]][$a[3]] = $value;
        }
    }


    private function _getSections($path)
    {
        $aSections = explode($this->_delem, $path);
        if (count($aSections) == 0) {
            throw new mpArrayManager_Exception('Invalid section path.');
        } elseif (count($aSections) > 4) {
            throw new mpArrayManager_Exception('Maximum provided section depth (4) is overrun.');
        }
        foreach ($aSections as $pos => $value) {
            if ((string) $value === '') {
                throw new mpArrayManager_Exception('Configuration section must be a non-empty string.');
            }
        }
        return $aSections;
    }

}